package com.learning.rocketmq.demo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.common.message.MessageExt;
import com.alibaba.rocketmq.remoting.exception.RemotingException;
import com.lotso.web.common.activemq.config.ActiveMqName;
import com.lotso.web.common.rocketmq.service.MQConsumeService;
import com.lotso.web.common.rocketmq.service.impl.AbstractMQMsgProcessor;
import com.lotso.web.common.utils.DateUtil;
import com.lotso.web.module.activemq.constant.ENUM_MQSTATE;
import com.lotso.web.module.activemq.constant.ENUM_TRANS_SERVICE;
import com.lotso.web.module.activemq.entity.MqInfoLog;
import com.lotso.web.module.activemq.entity.Mqlog;
import com.lotso.web.module.activemq.entity.TradeMqinfo;
import com.lotso.web.module.activemq.entity.TradeRequestDTO;
import com.lotso.web.module.activemq.entity.TransResultDTO;
import com.lotso.web.module.activemq.service.ITradeService;
import com.lotso.web.module.activemq.service.impl.IMqInfoLogServiceImpl;
import com.lotso.web.module.activemq.service.impl.MqlogServiceImpl;
import com.lotso.web.module.activemq.service.impl.TradeServiceFactory;
import com.lotso.web.module.paytrade.constant.ENUM_TRADE_STATUS;
import com.lotso.web.module.paytrade.controller.UnionWithHoldingController;
import com.lotso.web.module.paytrade.entity.PayTradeRequestDTO;
import com.lotso.web.module.system.service.impl.DictServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.List;

@Service
@Slf4j
@MQConsumeService(topic=TopicEnum.SFTOZF,tags={"*"})
public class QueueConsumerSF extends AbstractMQMsgProcessor{
    @Autowired
    private MqlogServiceImpl mqlogServiceImpl;
    @Autowired
    private IMqInfoLogServiceImpl iMqInfoLogServiceImpl;
    UnionWithHoldingController unionWithHoldingController;
    @Autowired
    DictServiceImpl dictService;
    @Autowired
    private DefaultMQProducer defaultMQProducer;
    @Resource
    public void setUnionWithHoldingController(
            UnionWithHoldingController unionWithHoldingController) {
        this.unionWithHoldingController = unionWithHoldingController;
    }
    //消息监听器
	@Override
	protected MQConsumeResult consumeMessage(String tag, List<String> keys, MessageExt messageExt) {
        String msg = new String(messageExt.getBody());
        MQConsumeResult result = new MQConsumeResult();
        result.setSuccess(true);
        log.info("支付平台接收统一收付平台mq消息处理开始");
        TradeRequestDTO tradeRequestDTO = new TradeRequestDTO();
        Mqlog mqlog = null;
        MqInfoLog mqInfoLog = new MqInfoLog();
        try {
            //获取收付平台传过来的mqlog对象数据
        	log.info("支付平台接收统一收付平台mq信息："+msg);
            JSONObject jsonObject = JSONObject.parseObject(msg);
            String mqlogstring=jsonObject.getString("mqlog");
            mqlog = JSON.parseObject(mqlogstring, Mqlog.class);
          /*  String id = mqlogOwer.getId();
            String operation = mqlogOwer.getOperation();
            String sfserialno = mqlogOwer.getSfserialno();*/
            //将获取到的mq的id、operation、sfserialno等信息封装到Mqlog、MqInfoLog对象中

            mqlog.setState(ENUM_MQSTATE.ZFJS.getValue());
            mqlog.setMakedate(DateUtil.now());
            mqlog.setMaketime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));
            mqlog.setModifydate(DateUtil.now());
            mqlog.setModifytime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));
            mqInfoLog.setId(mqlog.getId());
            mqInfoLog.setState("0");
            mqInfoLog.setJsoninfo(msg.getBytes("GBK"));
            mqInfoLog.setMqname(ActiveMqName.SFTOZF);
            mqInfoLog.setMakedate(DateUtil.now());
            mqInfoLog.setMaketime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));


            //解析请求对象
            String paytraderequestdto=jsonObject.getString("tradeRequestDTO");
            PayTradeRequestDTO payTradeRequestDTO = JSON.parseObject(paytraderequestdto, PayTradeRequestDTO.class);
            tradeRequestDTO.setBusinessDocumentCode(payTradeRequestDTO.getBusinessDocumentCode());
            tradeRequestDTO.setBusinessId(payTradeRequestDTO.getBusinessId());
            tradeRequestDTO.setBusinessType(payTradeRequestDTO.getBusinessType());
            tradeRequestDTO.setTradeType(payTradeRequestDTO.getTradeType());

            if(mqlogServiceImpl.insertMQ(mqlog)<1||iMqInfoLogServiceImpl.insertMQ(mqInfoLog)<1){
                log.error("支付平台接收mq消息保存失败!");
                tradeRequestDTO.setErrorMessage("支付平台接收mq消息保存失败!");
                sendErrorToSF(tradeRequestDTO,mqlog,mqInfoLog);
                return result;
            }
            if(StringUtils.isEmpty(mqlog.getOperation())){
                log.error("支付平台接收核心mq消息中收付类型有误");
                tradeRequestDTO.setErrorMessage("支付平台接收核心mq消息中收付类型有误");
                sendErrorToSF(tradeRequestDTO,mqlog,mqInfoLog);
                return result;
            }
            if(!ENUM_TRANS_SERVICE.serviceMap.containsKey(mqlog.getOperation())){
                log.error("支付平台接收核心mq消息中收付类型有误");
                tradeRequestDTO.setErrorMessage("支付平台接收核心mq消息中收付类型有误");
                sendErrorToSF(tradeRequestDTO,mqlog,mqInfoLog);
                return result;
            }

            //更新mqlog表状态6-落地
            mqlog.setState(ENUM_MQSTATE.ZFLD.getValue());
            mqlog.setModifydate(DateUtil.now());
            mqlog.setModifytime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));
            if(mqlogServiceImpl.updateMQ(mqlog)<1){
                log.error("更新mqlog表状态6-落地保存失败!" );
                tradeRequestDTO.setErrorMessage("支付平台更新mq消息失败!");
                sendErrorToSF(tradeRequestDTO,mqlog,mqInfoLog);
                return result;
            }

            TransResultDTO responseXml=null;
//            String paytraderequestdto=jsonObject.getString("tradeRequestDTO");
//            PayTradeRequestDTO payTradeRequestDTO = JSON.parseObject(paytraderequestdto, PayTradeRequestDTO.class);
            payTradeRequestDTO.setCallbackType("02");
            //回调状态
            payTradeRequestDTO.setCallbackState("0");
            responseXml=unionWithHoldingController.trade(msg, payTradeRequestDTO, null, null);
            //通过配置判断是否阻断
            String switchFlag =  dictService.selectValue("switch");

            if(responseXml == null && "open".equals(switchFlag)){
                return result;
            }

            String RFsafeswitchflag = dictService.selectValue("RFsafeswitch");
            //储备金不足不返回前端信息
            if(responseXml == null && "N".equals(RFsafeswitchflag)){
                return result;
            }

            log.info("请求返回报文对象："+ responseXml);

            //调完第三方接口，给mqlog表状态置为7-调用完第三方
            mqlog.setState(ENUM_MQSTATE.ZFDY.getValue());
            mqlog.setModifydate(DateUtil.now());
            mqlog.setModifytime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));
            if(mqlogServiceImpl.updateMQ(mqlog)<1){
                log.error("更新mqlog表状态7-调用完第三方落地失败!" );
                tradeRequestDTO.setErrorMessage("支付平台更新mq消息失败!");
                sendErrorToSF(tradeRequestDTO,mqlog,mqInfoLog);
                return result;
            }

            //支付平台返回消息给统一收付平台
            ITradeService tService = TradeServiceFactory.createProcessor(mqlog.getOperation());
            boolean sendSucc = tService.service(responseXml,mqlog,mqInfoLog);
            if(!sendSucc){
                log.info("支付结果返回收付平台异常");
                tradeRequestDTO.setErrorMessage("支付结果返回收付平台异常!");
                sendErrorToSF(tradeRequestDTO,mqlog,mqInfoLog);
            }

            //更新Mqlog对象状态:8-支付发送收付
            mqlog.setState(ENUM_MQSTATE.ZFFS.getValue());
            mqlog.setModifydate(DateUtil.now());
            mqlog.setModifytime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));
            if(mqlogServiceImpl.updateMQ(mqlog)<1){
                log.debug("TradeSinglePayService单笔代付更新mqlog信息8-已发送状态数据落地失败!");
                return result;
            }
            log.info("支付平台接收统一收付平台消息处理结束");
        }catch(Exception e){
            log.error("支付平台调用通道时处理异常！,错误信息:" + e.getMessage());
            tradeRequestDTO.setErrorMessage("支付平台调用通道时处理异常!");
            sendErrorToSF(tradeRequestDTO,mqlog,mqInfoLog);
        }
		return result;
    }

    public void sendErrorToSF(TradeRequestDTO tradeRequestDTO,Mqlog mqlog,MqInfoLog mqInfoLog){
        log.info("开始处理支付平台异常发回收付平台");
        TradeMqinfo tradeMqinfo = new TradeMqinfo();
        tradeRequestDTO.setTradeState(ENUM_TRADE_STATUS.XTCW.getCode());
        tradeMqinfo.setTradeRequestDTO(tradeRequestDTO);
        mqlog.setState(ENUM_MQSTATE.ERROR.getValue());
        mqlog.setModifydate(DateUtil.now());
        mqlog.setModifytime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));
        tradeMqinfo.setMqlog(mqlog);
		try {
			Message message = new Message(ActiveMqName.ZFTOSF, "sign", JSON.toJSONString(tradeMqinfo).getBytes());
			SendResult result = defaultMQProducer.send(message);
			log.info("sendResult:" + result);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
        //阻断报错，mq状态更新为F-系统错误
        mqInfoLog.setState(ENUM_MQSTATE.ERROR.getValue());
        mqInfoLog.setMqname(ActiveMqName.ZFTOSF);
        String json=JSON.toJSONString(tradeMqinfo);
        try {
            mqInfoLog.setJsoninfo(json.getBytes("GBK"));
        } catch (UnsupportedEncodingException e) {
            log.error("支付平台接收统一收付平台MQ处理异常！,错误信息:" + e.getMessage());
        }
        mqInfoLog.setMakedate(DateUtil.now());
        mqInfoLog.setMaketime(DateUtil.dateToString(DateUtil.now(), DateUtil.TIME_PATTERN));

        if(mqlogServiceImpl.updateMQ(mqlog)<1||iMqInfoLogServiceImpl.insertMQ(mqInfoLog)<1){
            log.debug("处理错误信息返回给收付平台时更新mq信息状态数据落地失败!");
        }

        log.info("异常推回收付平台完成");
    }
}
